﻿using System.Net;
using Transformable_Engine_v2.Engine.Global;
using Transformable_Engine_v2.Engine.Network;
using Transformable_Engine_v2.Engine.Network.Interfaces;
using Transformable_Engine_v2.Engine.Network.Object;

namespace AngryManagementMayhem.Controller
{
    public static class GameController
    {
        private const int SERVER_PORT = 3355;
        private const int CLIENT_PORT = 3356;

        private static string _gameName = "";
        private static GameMode _mode = GameMode.None;
        private static MapList _map = MapList.None;

        public static string GameName
        {
            get { return _gameName; }
            set { _gameName = value; }
        }

        public enum GameMode
        {
            None,
            CaptureTheFlag,
            DeathMatch,
            TeamDeathMatch,
        }
        public static GameMode Mode
        {
            get { return _mode; }
            set { _mode = value; }
        }

        public enum MapList
        {
            None,
            OfficeWars,
        }
        public static MapList Map
        {
            get { return _map; }
            set { _map = value; }
        }

        public static int MaxPlayers { get; set; }

        private static UdpNetworkClient _networkListener;

        public static void StartNetworkClient()
        {
            _networkListener = new UdpNetworkClient(BaseNetworkClient.ClientType.Async);
            _networkListener.OnReceive += OnReceiveNetworkMessage;

            if (System.Diagnostics.Debugger.IsAttached)
            {
                Log.LogDebug("Server started");
                _networkListener.Receive(IPAddress.Any, SERVER_PORT);
            }
            else
            {
                Log.LogDebug("Client started");
                _networkListener.Receive(IPAddress.Any, CLIENT_PORT);
            }
        }

        public static void BroadcastToFindServer(NetworkSerializableObject msg)
        {
            _networkListener.Send(IPAddress.Broadcast, SERVER_PORT, msg.Serialize());
        }

        public static void SendMessageToClient(IPAddress ip, NetworkSerializableObject msg)
        {
            _networkListener.Send(ip, CLIENT_PORT, msg.Serialize());
        }

        public static void SendMessageToServer(NetworkSerializableObject msg)
        {
            //_networkListener.Send(ip, port, msg.Serialize());
        }

        public delegate void OnNetworkSearchGameHandler(IPEndPoint sender, NetworkObject.SearchGame obj);
        public static event OnNetworkSearchGameHandler OnNetworkSearchGame;

        public delegate void OnNetworkSearchGameResponseHandler(IPEndPoint sender, NetworkObject.SearchGameResponse obj);
        public static event OnNetworkSearchGameResponseHandler OnNetworkSearchGameResponse;

        private static void OnReceiveNetworkMessage(IPEndPoint senderInfo, byte[] messageReceived)
        {
            Log.LogDebug("Network message received from " + senderInfo);

            NetworkSerializableObject obj = NetworkSerializableObject.Deserialize(messageReceived);

            switch (obj.Id)
            {
                case NetworkObject.SearchGame.ID:
                    if (OnNetworkSearchGame != null)
                        OnNetworkSearchGame(senderInfo, Serialization.Deserialize<NetworkObject.SearchGame>(obj.SerializableObject));
                    break;
                case NetworkObject.SearchGameResponse.ID:
                    if (OnNetworkSearchGameResponse != null)
                        OnNetworkSearchGameResponse(senderInfo, Serialization.Deserialize<NetworkObject.SearchGameResponse>(obj.SerializableObject));
                    break;
            }
        }
    }
}